package jp.tkym.labs.geom;

class TaylorExplore{
	private static double[] LEVEL_SIN = new double[]{
		0.13d, 
		0.55d, 
		1.13d, 
		1.78d, 
		2.46d
	};
	
	public static double sin(double x){
		if(x < LEVEL_SIN[0] && x > -LEVEL_SIN[0]) return sin(x, 0);
		if(x < LEVEL_SIN[1] && x > -LEVEL_SIN[1]) return sin(x, 1);
		if(x < LEVEL_SIN[2] && x > -LEVEL_SIN[2]) return sin(x, 2);
		if(x < LEVEL_SIN[3] && x > -LEVEL_SIN[3]) return sin(x, 3);
		if(x < LEVEL_SIN[4] && x > -LEVEL_SIN[4]) return sin(x, 4);
		return sin(x, 5);
	}
	
	static double sin(double x, int n){
		if(n < 0) throw new IllegalArgumentException("n is "+ n);
		double ret = x;
		double fx = x;
		if(n > 0) { fx = (fx*x*x); ret -= fx/6; }
		if(n > 1) { fx = (fx*x*x); ret += fx/120; }
		if(n > 2) { fx = (fx*x*x); ret -= fx/5040; }
		if(n > 3) { fx = (fx*x*x); ret += fx/362880; }
		if(n > 4) { fx = (fx*x*x); ret -= fx/39916800; }
		return ret;
	}
	
	private static double[] LEVEL_COS = new double[]{
			0.03d, 
			0.38d, 
			0.94d, 
			1.58d, 
			2.26d, 
			2.98d
		};
	
	public static double cos(double x){
		if(x < LEVEL_COS[0] && x > -LEVEL_COS[0]) return cos(x, 0);
		if(x < LEVEL_COS[1] && x > -LEVEL_COS[1]) return cos(x, 1);
		if(x < LEVEL_COS[2] && x > -LEVEL_COS[2]) return cos(x, 2);
		if(x < LEVEL_COS[3] && x > -LEVEL_COS[3]) return cos(x, 3);
		if(x < LEVEL_COS[4] && x > -LEVEL_COS[4]) return cos(x, 4);
		if(x < LEVEL_COS[5] && x > -LEVEL_COS[5]) return cos(x, 5);
		return cos(x, 6);
	}
	
	static double cos(double x, int n){
		if(n < 0) throw new IllegalArgumentException("n is "+ n);
		double ret = 1;
		double fx = 1;
		if(n > 0) { fx = (fx*x*x); ret -= fx/2; }
		if(n > 1) { fx = (fx*x*x); ret += fx/24; }
		if(n > 2) { fx = (fx*x*x); ret -= fx/720; }
		if(n > 3) { fx = (fx*x*x); ret += fx/40320; }
		if(n > 4) { fx = (fx*x*x); ret -= fx/3628800; }
		if(n > 5) { fx = (fx*x*x); ret += fx/479001600; }
		return ret;
	}
}